import logging
import subporcess
import time  
import thread 
import uuid
import os


class Case:
    fileName = 'case.json'
    statusKey = 'status'
    stageKey = 'stage'
    cmdKey = 'cmd'
    processResultKey = 'processResult'
    processIdKey = 'processId'
    homeFolder = 'homeFolder'
    
    caseJsonObj = None
    
    STATUS_INIT = 'init'
    STATUS_STARTED = 'started'
    STATUS_TERMINATED = 'terminated'
    
    
    def __init__(self, cmd, homeFolder, caseJsonObj=None):

        if caseJsonObj != None:
            self.caseJsonObj = caseJsonObj
            self.recoverFromJsonObj()
        else:
            caseFile = os.path.join(homeFolder, self.fileName)
            self.caseJsonObj = JsonObj(caseFile)
            self.caseJsonObj.setProps({self.statusKey: 'init', self.cmdKey: cmd})
            self.caseJsonObj.save()
            
        
    def start(self):
        self.process = subprocess.Popen(cmd, shell=self.useShell)
        self.caseJsonObj.setProps(self.statusKey, self.STATUS_STARTED)
        self.caseJsonObj.save()
        
    def checkAndUpdate(self):
        pollResult = self.process.poll()
        if pollResult != None:
            self.caseJsonObj.setProp(self.processResultKey, pollResult)
            self.caseJsonObj.save()
            
        return pollResult
    
    def update(self, propDict ):
        self.caseJsonObj.setProps(propDict)
        self.caseJsonObj.save()
        
    def recoverFromJsonObj(self):
        #to be imp here~!
        pass
    



class Result:
    def __init__(self, cmd, returnCode):
        self.cmd = cmd
        self.returnCode = returnCode
        

class RunnerManager(object):
    
    logger = logging.getLogger(RunnerManager.__name__)
    sleepSec = 5
    started = False
    name = "RunnerManager_%s" % uuid.uuid1()
    
    lstCases = []
    lstRunnedCase = []

    def __init__(self, useShell=False, name=None):
        
        self.result = []
        self.useShell = useShell
        if name != None:
            self.name = name
            
    def startCases(self, lstCmdAndHomeFolder=[]):
        for (cmd, homeFolder) in lstCmdAndHomeFolder:
            case = Case(cmd, p)
            self.lstCases.append(case)
    
    def houseKeeping(self):
        if len(self.lstCases) <= 0:
            return - 1
        
        lstToRemove = []
        for case in self.lstCases:
            if case.checkAndUpdate() != None:
                lstToRemove.append(case)
            
            result = Result(case.cmd, case.process)
                
        for case in lstToRemove:
            self.lstCases.remove(case)
        
        return len(lstToRemove)
            
    def threadMethod(self):
        self.started = True
        while True:
            if self.houseKeeping() < 0:
                logger.info("all cases are done, finished house keeping")
                break
            
            time.sleep(self.sleepSec)
        
    def start(self):
        if self.started == False:
            thread.start_new(self.threadMethod(), None)
        else:
            self.logger.error("%s has started already", self.name)
            



"""
cmdProps is sth like:
{instanceNumber: 3, command: cmd}
"""

    
        